Importing the libraries

library(tidyverse)
Registered S3 methods overwritten by 'dbplyr':
  method         from
  print.tbl_lazy     
  print.tbl_sql      
── Attaching packages ─────────────────────────────────────────────────────── tidyverse 1.3.1 ──
✓ ggplot2 3.3.5     ✓ purrr   0.3.4
✓ tibble  3.1.6     ✓ dplyr   1.0.8
✓ tidyr   1.2.0     ✓ stringr 1.4.0
✓ readr   2.1.2     ✓ forcats 0.5.1
── Conflicts ────────────────────────────────────────────────────────── tidyverse_conflicts() ──
x dplyr::filter() masks stats::filter()
x dplyr::lag()    masks stats::lag()
library(plotly)

Attaching package: ‘plotly’

The following object is masked from ‘package:ggplot2’:

    last_plot

The following object is masked from ‘package:stats’:

    filter

The following object is masked from ‘package:graphics’:

    layout
require(devtools)
Loading required package: devtools
Loading required package: usethis

Importing the data-set

# National Parks in California
ca = read_csv("https://raw.githubusercontent.com/ScienceParkStudyGroup/r-lesson-based-on-ohi-data-training/gh-pages/data/ca.csv") 
Rows: 789 Columns: 7
── Column specification ────────────────────────────────────────────────────────────────────────
Delimiter: ","
chr (5): region, state, code, park_name, type
dbl (2): visitors, year

ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
head(ca)

Analysing the data-type of the data

colnames(ca)
[1] "region"    "state"     "code"      "park_name" "type"      "visitors"  "year"     
str(ca)
spec_tbl_df [789 × 7] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
 $ region   : chr [1:789] "PW" "PW" "PW" "PW" ...
 $ state    : chr [1:789] "CA" "CA" "CA" "CA" ...
 $ code     : chr [1:789] "CHIS" "CHIS" "CHIS" "CHIS" ...
 $ park_name: chr [1:789] "Channel Islands National Park" "Channel Islands National Park" "Channel Islands National Park" "Channel Islands National Park" ...
 $ type     : chr [1:789] "National Park" "National Park" "National Park" "National Park" ...
 $ visitors : num [1:789] 1200 1500 1600 300 15700 ...
 $ year     : num [1:789] 1963 1964 1965 1966 1967 ...
 - attr(*, "spec")=
  .. cols(
  ..   region = col_character(),
  ..   state = col_character(),
  ..   code = col_character(),
  ..   park_name = col_character(),
  ..   type = col_character(),
  ..   visitors = col_double(),
  ..   year = col_double()
  .. )
 - attr(*, "problems")=<externalptr> 

Plot-1 –> ggplot2

Bar Plot

labs = c(
         'CHIS'='Channel Islands National Park',
         'DEVA'='Death Valley National Park',
         'JOTR'='Joshua Tree National Park',
         'KICA'='Kings Canyon National Park',
         'LAVO'='Lassen Volcanic National Park',
         'YOSE'='Yosemite National Park',
         'SEQU'='Sequoia National Park',
         'REDW'='Redwood National Park',
         'PINN'='Pinnacles National Park'
         )
bar_plot = ggplot(data=ca, aes(x = code, y = ..count.. / sum(..count..),fill = factor(code))) +
           geom_bar(color='black') + 
           labs(x = "National Parks", y = "Percentage of National Parks in the data-set", 
                title = "Occurence of the National Parks in the data-set") +
  
           scale_x_discrete(labels =labs)
           scale_y_continuous(labels = scales::percent)
<ScaleContinuousPosition>
 Range:  
 Limits:    0 --    1
           
bar_plot + coord_flip()

Kernel Density Plot

density_plot = ggplot(data=ca, aes(x =log10(visitors))) +
                geom_density(fill = "indianred3") +
                labs(x = "brain weight", y="density", title="Kernal density of the brain weight")
density_plot       

Plot-2 –> plotly

Scatter plot

t <- list(family = "Helvetica",size = 14,color = "blue")
t1 <- list(family = "Times New Roman",color = "red")
t2 <- list(family = "Courier New",size = 14,color = "green")
t3 <- list(family = 'Arial')
scatter_plot = plot_ly(data=ca, x=~year, y=~visitors,color = ~park_name, type='scatter',mode='markers') %>%
                       layout(
                          title= list(text = "<b>Body weight vs Brain weight"),
                          legend = list(title = list(text ='<b>Animals')), 
                          xaxis  = list(title = list(text ='<b>Brain Weight')),
                          yaxis  = list(title = list(text ='<b>Body Weight')),
                          plot_bgcolor='#e5ecf6')
scatter_plot
Warning in RColorBrewer::brewer.pal(N, "Set2") :
  n too large, allowed maximum for palette Set2 is 8
Returning the palette you asked for with that many colors

Warning in RColorBrewer::brewer.pal(N, "Set2") :
  n too large, allowed maximum for palette Set2 is 8
Returning the palette you asked for with that many colors

Warning in RColorBrewer::brewer.pal(N, "Set2") :
  n too large, allowed maximum for palette Set2 is 8
Returning the palette you asked for with that many colors

Warning in RColorBrewer::brewer.pal(N, "Set2") :
  n too large, allowed maximum for palette Set2 is 8
Returning the palette you asked for with that many colors

Barchart

r_group_barchart = data.table::melt(ca, id.vars='park_name') %>%
plot_ly(x = ~park_name, y = ~value, type = 'bar', name = ~variable, color = ~variable) %>%
      layout(
          title= list(text = "<b>Total Distribution based on Vore"),
          legend = list(title = list(text= '<b>Aniamal Feature')),
          xaxis  = list(title = list(text ='<b>Vores')),
          yaxis = list(title='Count', text='<b>Count'), barmode = 'group')
Warning in data.table::melt(ca, id.vars = "park_name") :
  The melt generic in data.table has been passed a spec_tbl_df and will attempt to redirect to the relevant reshape2 method; please note that reshape2 is deprecated, and this redirection is now deprecated as well. To continue using melt methods from reshape2 while both libraries are attached, e.g. melt.list, you can prepend the namespace like reshape2::melt(ca). In the next version, this warning will become an error.
r_group_barchart

Pie-chart

df_order = data.frame(table(ca$park_name))
df_order
pie_chart = plot_ly(type='pie', labels=df_order$Var1, values=df_order$Freq, 
                    textinfo='label+percent',insidetextorientation='radial') %>%
                    layout(
                          title= list(text = "<b>Order Distributions"),
                          legend = list(title = list(text= '<b>Order')))

pie_chart

Histogram Plots

histogram_plot = plot_ly(data = ca, x = ~(log(visitors)), name=~code,type="histogram") %>%
                  layout(
                          title= list(text = "<b>Total sleep time of Animals based on Vore"),
                          legend = list(title = list(text= '<b>Vore')),
                          xaxis  = list(title = list(text ='<b>Visitors')),
                          yaxis  = list(title = list(text ='<b>Count')))
histogram_plot

Donut Chart / Open Pie-Chart

df_vore = data.frame(table(ca$code))
df_vore
donut_chart = plot_ly(labels=df_vore$Var1, values=df_vore$Freq, 
                    textinfo='label+percent') %>%
                    add_pie(hole = 0.6) %>%
                    layout(
                          title= list(text = "<b>Order Distributions"),
                          legend = list(title = list(text= '<b>Order')))

donut_chart

Plot-4 –> gganimate

library(gganimate)
library(gifski)

Animate –> Scatter Plot

#scatter_plot_animate = ggplot(data=ca, aes(year, visitors)) + geom_point() +                
#                       transition_states(park_name)
#animate(scatter_plot_animate, renderer = gifski_renderer())

Animate –> Line Plot

## filtering out only 'CHIS', 'DEVA' AND 'JOTR' Park_code
d = ca %>%
    filter(code%in%c('CHIS', 'DEVA', 'JOTR'))
d
#line_plot = ggplot(d, aes(x=year, y=visitors, group=code, color=code)) + 
#                   geom_line() + geom_point() + 
#                   transition_reveal(year)

#animate(line_plot, width=300, height=300, renderer = gifski_renderer())

Visitors started to visit Channel Islands National Park in 1960’s (latest among) has very low visitors till date. Joshua Tree National Park has a continuous growth of visitors without a big drop. Death Valley National Park has a continuous growth of visitors in 2010’s and a gradual pick-up.

library(dplyr)
state_map = map_data('state')
head(state_map)
data = state.x77
data = as.data.frame(data)
data$region = tolower(rownames(data))
head(data)
data_join = left_join(state_map, data, by='region')
head(data_join)
ggplot(data=data_join, aes(x=long, y=lat, group=group),
       color='white', fill=population) + 
       geom_polygon() + 
       scale_fill_viridis_d(option='A')

df = read.csv('zomato.csv')
head(df)
LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKIyMgSW1wb3J0aW5nIHRoZSBsaWJyYXJpZXMKYGBge3J9CmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KHBsb3RseSkKCnJlcXVpcmUoZGV2dG9vbHMpCmBgYAoKIyMgSW1wb3J0aW5nIHRoZSBkYXRhLXNldApgYGB7cn0KIyBOYXRpb25hbCBQYXJrcyBpbiBDYWxpZm9ybmlhCmNhID0gcmVhZF9jc3YoImh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9TY2llbmNlUGFya1N0dWR5R3JvdXAvci1sZXNzb24tYmFzZWQtb24tb2hpLWRhdGEtdHJhaW5pbmcvZ2gtcGFnZXMvZGF0YS9jYS5jc3YiKSAKCmhlYWQoY2EpCmBgYAoKIyMgQW5hbHlzaW5nIHRoZSBkYXRhLXR5cGUgb2YgdGhlIGRhdGEKYGBge3J9CmNvbG5hbWVzKGNhKQpgYGAKCmBgYHtyfQpzdHIoY2EpCmBgYAoKIyMgUGxvdC0xIC0tPiBnZ3Bsb3QyCiMjIyBCYXIgUGxvdApgYGB7cn0KbGFicyA9IGMoCiAgICAgICAgICdDSElTJz0nQ2hhbm5lbCBJc2xhbmRzIE5hdGlvbmFsIFBhcmsnLAogICAgICAgICAnREVWQSc9J0RlYXRoIFZhbGxleSBOYXRpb25hbCBQYXJrJywKICAgICAgICAgJ0pPVFInPSdKb3NodWEgVHJlZSBOYXRpb25hbCBQYXJrJywKICAgICAgICAgJ0tJQ0EnPSdLaW5ncyBDYW55b24gTmF0aW9uYWwgUGFyaycsCiAgICAgICAgICdMQVZPJz0nTGFzc2VuIFZvbGNhbmljIE5hdGlvbmFsIFBhcmsnLAogICAgICAgICAnWU9TRSc9J1lvc2VtaXRlIE5hdGlvbmFsIFBhcmsnLAogICAgICAgICAnU0VRVSc9J1NlcXVvaWEgTmF0aW9uYWwgUGFyaycsCiAgICAgICAgICdSRURXJz0nUmVkd29vZCBOYXRpb25hbCBQYXJrJywKICAgICAgICAgJ1BJTk4nPSdQaW5uYWNsZXMgTmF0aW9uYWwgUGFyaycKICAgICAgICAgKQpgYGAKCgpgYGB7cn0KYmFyX3Bsb3QgPSBnZ3Bsb3QoZGF0YT1jYSwgYWVzKHggPSBjb2RlLCB5ID0gLi5jb3VudC4uIC8gc3VtKC4uY291bnQuLiksZmlsbCA9IGZhY3Rvcihjb2RlKSkpICsKICAgICAgICAgICBnZW9tX2Jhcihjb2xvcj0nYmxhY2snKSArIAogICAgICAgICAgIGxhYnMoeCA9ICJOYXRpb25hbCBQYXJrcyIsIHkgPSAiUGVyY2VudGFnZSBvZiBOYXRpb25hbCBQYXJrcyBpbiB0aGUgZGF0YS1zZXQiLCAKICAgICAgICAgICAgICAgIHRpdGxlID0gIk9jY3VyZW5jZSBvZiB0aGUgTmF0aW9uYWwgUGFya3MgaW4gdGhlIGRhdGEtc2V0IikgKwogIAogICAgICAgICAgIHNjYWxlX3hfZGlzY3JldGUobGFiZWxzID1sYWJzKQogICAgICAgICAgIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnQpCiAgICAgICAgICAgCmJhcl9wbG90ICsgY29vcmRfZmxpcCgpCmBgYAoKIyMjIEtlcm5lbCBEZW5zaXR5IFBsb3QKYGBge3J9CmRlbnNpdHlfcGxvdCA9IGdncGxvdChkYXRhPWNhLCBhZXMoeCA9bG9nMTAodmlzaXRvcnMpKSkgKwogICAgICAgICAgICAgICAgZ2VvbV9kZW5zaXR5KGZpbGwgPSAiaW5kaWFucmVkMyIpICsKICAgICAgICAgICAgICAgIGxhYnMoeCA9ICJicmFpbiB3ZWlnaHQiLCB5PSJkZW5zaXR5IiwgdGl0bGU9Iktlcm5hbCBkZW5zaXR5IG9mIHRoZSBicmFpbiB3ZWlnaHQiKQpkZW5zaXR5X3Bsb3QgICAgICAgCmBgYAojIyBQbG90LTIgLS0+IHBsb3RseQojIyMgU2NhdHRlciBwbG90CgpgYGB7cn0KdCA8LSBsaXN0KGZhbWlseSA9ICJIZWx2ZXRpY2EiLHNpemUgPSAxNCxjb2xvciA9ICJibHVlIikKdDEgPC0gbGlzdChmYW1pbHkgPSAiVGltZXMgTmV3IFJvbWFuIixjb2xvciA9ICJyZWQiKQp0MiA8LSBsaXN0KGZhbWlseSA9ICJDb3VyaWVyIE5ldyIsc2l6ZSA9IDE0LGNvbG9yID0gImdyZWVuIikKdDMgPC0gbGlzdChmYW1pbHkgPSAnQXJpYWwnKQpgYGAKCmBgYHtyfQpzY2F0dGVyX3Bsb3QgPSBwbG90X2x5KGRhdGE9Y2EsIHg9fnllYXIsIHk9fnZpc2l0b3JzLGNvbG9yID0gfnBhcmtfbmFtZSwgdHlwZT0nc2NhdHRlcicsbW9kZT0nbWFya2VycycpICU+JQogICAgICAgICAgICAgICAgICAgICAgIGxheW91dCgKICAgICAgICAgICAgICAgICAgICAgICAgICB0aXRsZT0gbGlzdCh0ZXh0ID0gIjxiPkJvZHkgd2VpZ2h0IHZzIEJyYWluIHdlaWdodCIpLAogICAgICAgICAgICAgICAgICAgICAgICAgIGxlZ2VuZCA9IGxpc3QodGl0bGUgPSBsaXN0KHRleHQgPSc8Yj5BbmltYWxzJykpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICB4YXhpcyAgPSBsaXN0KHRpdGxlID0gbGlzdCh0ZXh0ID0nPGI+QnJhaW4gV2VpZ2h0JykpLAogICAgICAgICAgICAgICAgICAgICAgICAgIHlheGlzICA9IGxpc3QodGl0bGUgPSBsaXN0KHRleHQgPSc8Yj5Cb2R5IFdlaWdodCcpKSwKICAgICAgICAgICAgICAgICAgICAgICAgICBwbG90X2JnY29sb3I9JyNlNWVjZjYnKQpzY2F0dGVyX3Bsb3QKYGBgCgojIyMgQmFyY2hhcnQKYGBge3J9CnJfZ3JvdXBfYmFyY2hhcnQgPSBkYXRhLnRhYmxlOjptZWx0KGNhLCBpZC52YXJzPSdwYXJrX25hbWUnKSAlPiUKcGxvdF9seSh4ID0gfnBhcmtfbmFtZSwgeSA9IH52YWx1ZSwgdHlwZSA9ICdiYXInLCBuYW1lID0gfnZhcmlhYmxlLCBjb2xvciA9IH52YXJpYWJsZSkgJT4lCiAgICAgIGxheW91dCgKICAgICAgICAgIHRpdGxlPSBsaXN0KHRleHQgPSAiPGI+VG90YWwgRGlzdHJpYnV0aW9uIGJhc2VkIG9uIFZvcmUiKSwKICAgICAgICAgIGxlZ2VuZCA9IGxpc3QodGl0bGUgPSBsaXN0KHRleHQ9ICc8Yj5BbmlhbWFsIEZlYXR1cmUnKSksCiAgICAgICAgICB4YXhpcyAgPSBsaXN0KHRpdGxlID0gbGlzdCh0ZXh0ID0nPGI+Vm9yZXMnKSksCiAgICAgICAgICB5YXhpcyA9IGxpc3QodGl0bGU9J0NvdW50JywgdGV4dD0nPGI+Q291bnQnKSwgYmFybW9kZSA9ICdncm91cCcpCnJfZ3JvdXBfYmFyY2hhcnQKYGBgCgojIyMgUGllLWNoYXJ0CmBgYHtyfQpkZl9vcmRlciA9IGRhdGEuZnJhbWUodGFibGUoY2EkcGFya19uYW1lKSkKZGZfb3JkZXIKYGBgCgpgYGB7cn0KcGllX2NoYXJ0ID0gcGxvdF9seSh0eXBlPSdwaWUnLCBsYWJlbHM9ZGZfb3JkZXIkVmFyMSwgdmFsdWVzPWRmX29yZGVyJEZyZXEsIAogICAgICAgICAgICAgICAgICAgIHRleHRpbmZvPSdsYWJlbCtwZXJjZW50JyxpbnNpZGV0ZXh0b3JpZW50YXRpb249J3JhZGlhbCcpICU+JQogICAgICAgICAgICAgICAgICAgIGxheW91dCgKICAgICAgICAgICAgICAgICAgICAgICAgICB0aXRsZT0gbGlzdCh0ZXh0ID0gIjxiPk9yZGVyIERpc3RyaWJ1dGlvbnMiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICBsZWdlbmQgPSBsaXN0KHRpdGxlID0gbGlzdCh0ZXh0PSAnPGI+T3JkZXInKSkpCgpwaWVfY2hhcnQKYGBgCgojIyMgSGlzdG9ncmFtIFBsb3RzCmBgYHtyfQpoaXN0b2dyYW1fcGxvdCA9IHBsb3RfbHkoZGF0YSA9IGNhLCB4ID0gfihsb2codmlzaXRvcnMpKSwgbmFtZT1+Y29kZSx0eXBlPSJoaXN0b2dyYW0iKSAlPiUKICAgICAgICAgICAgICAgICAgbGF5b3V0KAogICAgICAgICAgICAgICAgICAgICAgICAgIHRpdGxlPSBsaXN0KHRleHQgPSAiPGI+VG90YWwgc2xlZXAgdGltZSBvZiBBbmltYWxzIGJhc2VkIG9uIFZvcmUiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICBsZWdlbmQgPSBsaXN0KHRpdGxlID0gbGlzdCh0ZXh0PSAnPGI+Vm9yZScpKSwKICAgICAgICAgICAgICAgICAgICAgICAgICB4YXhpcyAgPSBsaXN0KHRpdGxlID0gbGlzdCh0ZXh0ID0nPGI+VmlzaXRvcnMnKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgeWF4aXMgID0gbGlzdCh0aXRsZSA9IGxpc3QodGV4dCA9JzxiPkNvdW50JykpKQpoaXN0b2dyYW1fcGxvdApgYGAKCiMjIyBEb251dCBDaGFydCAvIE9wZW4gUGllLUNoYXJ0CmBgYHtyfQpkZl92b3JlID0gZGF0YS5mcmFtZSh0YWJsZShjYSRjb2RlKSkKZGZfdm9yZQpgYGAKCmBgYHtyfQpkb251dF9jaGFydCA9IHBsb3RfbHkobGFiZWxzPWRmX3ZvcmUkVmFyMSwgdmFsdWVzPWRmX3ZvcmUkRnJlcSwgCiAgICAgICAgICAgICAgICAgICAgdGV4dGluZm89J2xhYmVsK3BlcmNlbnQnKSAlPiUKICAgICAgICAgICAgICAgICAgICBhZGRfcGllKGhvbGUgPSAwLjYpICU+JQogICAgICAgICAgICAgICAgICAgIGxheW91dCgKICAgICAgICAgICAgICAgICAgICAgICAgICB0aXRsZT0gbGlzdCh0ZXh0ID0gIjxiPk9yZGVyIERpc3RyaWJ1dGlvbnMiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICBsZWdlbmQgPSBsaXN0KHRpdGxlID0gbGlzdCh0ZXh0PSAnPGI+T3JkZXInKSkpCgpkb251dF9jaGFydApgYGAKCiMjIFBsb3QtNCAtLT4gZ2dhbmltYXRlCmBgYHtyfQpsaWJyYXJ5KGdnYW5pbWF0ZSkKbGlicmFyeShnaWZza2kpCmBgYAoKIyMjIEFuaW1hdGUgLS0+IFNjYXR0ZXIgUGxvdApgYGB7cn0KI3NjYXR0ZXJfcGxvdF9hbmltYXRlID0gZ2dwbG90KGRhdGE9Y2EsIGFlcyh5ZWFyLCB2aXNpdG9ycykpICsgZ2VvbV9wb2ludCgpICsgICAgICAgICAgICAgICAgCiMgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zaXRpb25fc3RhdGVzKHBhcmtfbmFtZSkKI2FuaW1hdGUoc2NhdHRlcl9wbG90X2FuaW1hdGUsIHJlbmRlcmVyID0gZ2lmc2tpX3JlbmRlcmVyKCkpCmBgYAoKIyMjIEFuaW1hdGUgLS0+IExpbmUgUGxvdApgYGB7cn0KIyMgZmlsdGVyaW5nIG91dCBvbmx5ICdDSElTJywgJ0RFVkEnIEFORCAnSk9UUicgUGFya19jb2RlCmQgPSBjYSAlPiUKICAgIGZpbHRlcihjb2RlJWluJWMoJ0NISVMnLCAnREVWQScsICdKT1RSJykpCmQKYGBgCgpgYGB7cn0KI2xpbmVfcGxvdCA9IGdncGxvdChkLCBhZXMoeD15ZWFyLCB5PXZpc2l0b3JzLCBncm91cD1jb2RlLCBjb2xvcj1jb2RlKSkgKyAKIyAgICAgICAgICAgICAgICAgICBnZW9tX2xpbmUoKSArIGdlb21fcG9pbnQoKSArIAojICAgICAgICAgICAgICAgICAgIHRyYW5zaXRpb25fcmV2ZWFsKHllYXIpCgojYW5pbWF0ZShsaW5lX3Bsb3QsIHdpZHRoPTMwMCwgaGVpZ2h0PTMwMCwgcmVuZGVyZXIgPSBnaWZza2lfcmVuZGVyZXIoKSkKYGBgClZpc2l0b3JzIHN0YXJ0ZWQgdG8gdmlzaXQgQ2hhbm5lbCBJc2xhbmRzIE5hdGlvbmFsIFBhcmsgaW4gMTk2MCdzIChsYXRlc3QgYW1vbmcpIGhhcyB2ZXJ5IGxvdyB2aXNpdG9ycyB0aWxsIGRhdGUuCkpvc2h1YSBUcmVlIE5hdGlvbmFsIFBhcmsgaGFzIGEgY29udGludW91cyBncm93dGggb2YgdmlzaXRvcnMgd2l0aG91dCBhIGJpZyBkcm9wLgpEZWF0aCBWYWxsZXkgTmF0aW9uYWwgUGFyayBoYXMgYSBjb250aW51b3VzIGdyb3d0aCBvZiB2aXNpdG9ycyBpbiAyMDEwJ3MgYW5kIGEgZ3JhZHVhbCBwaWNrLXVwLgoKYGBge3J9CmxpYnJhcnkoZHBseXIpCmBgYAoKYGBge3J9CnN0YXRlX21hcCA9IG1hcF9kYXRhKCdzdGF0ZScpCmhlYWQoc3RhdGVfbWFwKQpgYGAKCmBgYHtyfQpkYXRhID0gc3RhdGUueDc3CmRhdGEgPSBhcy5kYXRhLmZyYW1lKGRhdGEpCmRhdGEkcmVnaW9uID0gdG9sb3dlcihyb3duYW1lcyhkYXRhKSkKaGVhZChkYXRhKQpgYGAKCmBgYHtyfQpkYXRhX2pvaW4gPSBsZWZ0X2pvaW4oc3RhdGVfbWFwLCBkYXRhLCBieT0ncmVnaW9uJykKaGVhZChkYXRhX2pvaW4pCmBgYAoKYGBge3J9CmdncGxvdChkYXRhPWRhdGFfam9pbiwgYWVzKHg9bG9uZywgeT1sYXQsIGdyb3VwPWdyb3VwKSwKICAgICAgIGNvbG9yPSd3aGl0ZScsIGZpbGw9cG9wdWxhdGlvbikgKyAKICAgICAgIGdlb21fcG9seWdvbigpICsgCiAgICAgICBzY2FsZV9maWxsX3ZpcmlkaXNfZChvcHRpb249J0EnKQpgYGAKCmBgYHtyfQoKYGBgCgpgYGB7cn0KCmBgYAoKYGBge3J9CmRmID0gcmVhZC5jc3YoJ3pvbWF0by5jc3YnKQpoZWFkKGRmKQpgYGAKCmBgYHtyfQoKYGBgCgpgYGB7cn0KCmBgYAoKYGBge3J9CgpgYGAKCmBgYHtyfQoKYGBgCg==